import os

def parse_json_like_file(file_path):
    """
    手动解析类似 JSON 格式的文件。
    假设文件内容是合法的 Python 字典或列表格式。
    """
    data = []
    try:
        with open(file_path, "r") as file:
            content = file.read().strip()
            if not content:
                return data

            # 如果是列表格式
            if content.startswith("[") and content.endswith("]"):
                content = content[1:-1]  # 去掉外层的方括号
                items = content.split("},")
                for item in items:
                    item = item.strip()
                    if not item.endswith("}"):
                        item += "}"  # 补全可能缺失的右大括号
                    data.append(eval(item))  # 使用 eval 解析为字典
            # 如果是字典格式
            elif content.startswith("{") and content.endswith("}"):
                data = eval(content)  # 直接解析为字典
            else:
                raise ValueError("Unsupported file format.")
    except Exception as e:
        raise ValueError(f"Failed to parse file: {e}")
    return data


def load_data():
    """
    加载学生、课程和成绩数据。
    """
    students = []
    courses = {}
    grades = {}

    try:
        # 获取当前脚本所在目录
        current_dir = os.path.dirname(os.path.abspath(__file__))

        # 构建 student.json 的绝对路径
        student_path = os.path.join(current_dir, "student.json")
        course_path = os.path.join(current_dir, "course.json")
        grade_path = os.path.join(current_dir, "grades.json")

        # Load students
        student_data = parse_json_like_file(student_path)
        for student_info in student_data.get("students", []):
            student = {
                "username": student_info["username"],
                "fullName": student_info["fullName"],
                "age": student_info["age"],
                "school": student_info["school"],
                "interests": student_info["interests"],
                "relations": student_info["relations"],
                "followed_courses": student_info["followed_courses"]
            }
            students.append(student)

        # Load courses
        course_data = parse_json_like_file(course_path)
        for course_info in course_data.get("courses", []):
            course = {
                "courseId": course_info["courseId"],
                "title": course_info["title"],
                "department": course_info["department"],
                "credits": course_info["credits"],
                "professor": course_info["professor"],
                "schedule": course_info["schedule"],
                "description": course_info["description"],
                "prerequisites": course_info["prerequisites"]
            }
            courses[course["courseId"]] = course

        # Load grades
        grade_data = parse_json_like_file(grade_path)
        grades.update(grade_data.get("grades_per_course", {}))

    except FileNotFoundError as e:
        raise FileNotFoundError(f"File '{e.filename}' not found. Please ensure the file exists.")
    except Exception as e:
        raise ValueError(f"Error loading data: {e}")

    return students, courses, grades


def quick_sort(arr, key_func):
    """
    使用列表推导式实现快速排序。
    :param arr: 要排序的列表
    :param key_func: 用于提取排序键值的函数
    :return: 排序后的列表
    """
    if len(arr) <= 1:
        return arr
    pivot = arr[0]
    pivot_key = key_func(pivot)
    less = [x for x in arr[1:] if key_func(x) < pivot_key]
    greater = [x for x in arr[1:] if key_func(x) >= pivot_key]
    return quick_sort(less, key_func) + [pivot] + quick_sort(greater, key_func)


def sort_students_by_name(students):
    """
    按学生姓名排序。
    """
    return quick_sort(students, key_func=lambda x: x["fullName"])


def sort_students_by_total_grade(students, grades):
    """
    按学生的总成绩排序。
    """
    def total_grade(student):
        return sum([sum(scores) for scores in grades.get(student["username"], {}).values()])

    return quick_sort(students, key_func=total_grade)[::-1]  # 逆序返回以实现降序


def sort_students_by_course_grade(students, grades, course_id):
    """
    按特定课程的成绩排序。
    """
    def course_grade(student):
        return sum(grades.get(course_id, {}).get(student["username"], []))

    return quick_sort(students, key_func=course_grade)[::-1]  # 逆序返回以实现降序


def search_student_by_id(students, student_id):
    """
    根据学生 ID 搜索学生信息。
    :param students: 学生列表
    :param student_id: 学生 ID（username）
    :return: 学生信息字典，如果未找到返回 None
    """
    for student in students:
        if student["username"] == student_id:
            return student
    return None


def search_course_by_id(courses, course_id):
    """
    根据课程编号搜索课程详细信息。
    :param courses: 课程字典
    :param course_id: 课程编号
    :return: 课程信息字典，如果未找到返回 None
    """
    return courses.get(course_id, None)

def check_prerequisites(student, course, courses):
    """
    检查学生是否满足课程的前置条件。
    :param student: 学生信息字典
    :param course: 课程信息字典
    :param courses: 所有课程字典
    :return: True 如果满足前置条件，否则 False
    """
    prerequisites = course.get("prerequisites", [])
    followed_courses = student.get("followed_courses", [])
    return all(prereq in followed_courses for prereq in prerequisites)


def check_schedule_conflict(student, course, courses):
    """
    检查学生的时间表是否有冲突。
    :param student: 学生信息字典
    :param course: 课程信息字典
    :param courses: 所有课程字典
    :return: True 如果有冲突，否则 False
    """
    new_days = set(course["schedule"]["days"])
    new_time = course["schedule"]["time"]

    for course_id in student.get("followed_courses", []):
        existing_course = courses.get(course_id)
        if existing_course:
            existing_days = set(existing_course["schedule"]["days"])
            existing_time = existing_course["schedule"]["time"]
            if new_days & existing_days and new_time == existing_time:
                return True  # 时间冲突
    return False


def add_course_to_student(student, course_id, courses):
    """
    将课程添加到学生的时间表中。
    :param student: 学生信息字典
    :param course_id: 要添加的课程 ID
    :param courses: 所有课程字典
    :return: 成功或失败的消息
    """
    course = courses.get(course_id)
    if not course:
        return "Course not found."

    if course_id in student.get("followed_courses", []):
        return "Student is already enrolled in this course."

    if not check_prerequisites(student, course, courses):
        return "Prerequisites not met."

    if check_schedule_conflict(student, course, courses):
        return "Schedule conflict detected."

    student.setdefault("followed_courses", []).append(course_id)
    return f"Successfully added course {course_id} to student."


def remove_course_from_student(student, course_id):
    """
    从学生的时间表中移除课程。
    :param student: 学生信息字典
    :param course_id: 要移除的课程 ID
    :return: 成功或失败的消息
    """
    followed_courses = student.get("followed_courses", [])
    if course_id not in followed_courses:
        return "Student is not enrolled in this course."

    followed_courses.remove(course_id)
    return f"Successfully removed course {course_id} from student."